/*
 * Copyright (C) 2021 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package me.minetsh.imaging.photoview.ui;

import me.minetsh.imaging.ResourceTable;
import me.minetsh.imaging.photoview.adapter.ImageFolderAdapter;
import me.minetsh.imaging.photoview.adapter.ImageRecyclerProvider;
import me.minetsh.imaging.imageData.*;
import me.minetsh.imaging.photoview.bean.ImageItem;
import ohos.aafwk.content.Intent;
import ohos.agp.animation.AnimatorValue;
import ohos.agp.colors.RgbColor;
import ohos.agp.components.*;
import ohos.agp.components.element.ShapeElement;
import ohos.agp.utils.Color;
import ohos.bundle.IBundleManager;
import ohos.global.resource.NotExistException;
import ohos.global.resource.ResourceManager;
import ohos.global.resource.WrongTypeException;
import ohos.security.SystemPermission;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * ================================================
 * 作    者：jeasonlzy（廖子尧 Github地址：https://github.com/jeasonlzy0216
 * 版    本：1.0
 * 创建日期：2016/5/19
 * 描    述：
 * 修订历史：
 * 2017-03-17
 *
 * @author nanchen
 * 新增可直接传递是否裁剪参数，以及直接拍照
 * ================================================
 */
public class ImageGridAbility extends ImageBaseAbility implements ImageDataSource.OnImagesLoadedListener, ImageRecyclerProvider.OnImageItemClickListener, ImagePicker.OnImageSelectedListener, Component.ClickedListener {

    /**
     * 请求权限存储
     */
    public static final int REQUEST_PERMISSION_STORAGE = 0x01;
    /**
     * 请求许可相机
     */
    public static final int REQUEST_PERMISSION_CAMERA = 0x02;
    /**
     * 选择器
     */
    public static final String EXTRAS_TAKE_PICKERS = "TAKE";
    /**
     * 附加图像
     */
    public static final String EXTRAS_IMAGES = "IMAGES";

    private ImagePicker imagePicker;

    private Component mFooterBar; // 底部栏
    private Button mBtnOk; // 确定按钮
    private Component mllDir; // 文件夹切换按钮
    private Text mtvDir; // 显示当前文件夹
    private AnimatorValue animatorValue;
    private Text mBtnPre; // 预览按钮
    private ImageFolderAdapter mImageFolderAdapter; // 图片文件夹的适配器
    private List<ImageFolder> mImageFolders; // 所有的图片文件夹
    private boolean directPhoto = false; // 默认不是直接调取相机
    private ListContainer listContainer;
    private ImageRecyclerProvider listProvider;

    private ListContainer imageFileListContainer;

    @Override
    protected void onStart(Intent data) {
        super.onStart(data);
        ResourceManager resManager = this.getResourceManager();

        setUIContent(ResourceTable.Layout_ability_image_grid);

        imagePicker = ImagePicker.getInstance();
        imagePicker.clear();
        imagePicker.addOnImageSelectedListener(this);
        String maxCount = getIntent().getStringParam("max_count");
        try {
            int count = Integer.parseInt(maxCount);
            imagePicker.setSelectLimit(count);
        } catch (NumberFormatException e) {
            imagePicker.setSelectLimit(9);
        }
        // 新增可直接拍照
        if (data != null && data.getParams() != null) {
            directPhoto = data.getBooleanParam(EXTRAS_TAKE_PICKERS, false); // 默认不是直接打开相机
            if (directPhoto) {
                if (verifySelfPermission(SystemPermission.CAMERA) != IBundleManager.PERMISSION_GRANTED) {
                    requestPermissionsFromUser(new String[]{SystemPermission.CAMERA}, ImageGridAbility.REQUEST_PERMISSION_CAMERA);
                } else {
                    takePic();
                }
            }
            ArrayList<ImageItem> images = (ArrayList<ImageItem>) data.getSerializableParam(EXTRAS_IMAGES);
            imagePicker.setSelectedImages(images);
        }

        listContainer = (ListContainer) findComponentById(ResourceTable.Id_recycler);
        TableLayoutManager tableLayoutManager = new TableLayoutManager();
        tableLayoutManager.setColumnCount(3);
        listContainer.setLayoutManager(tableLayoutManager);

        imageFileListContainer = (ListContainer) findComponentById(ResourceTable.Id_image_file_list);

        DependentLayout titleLayout = (DependentLayout) findComponentById(ResourceTable.Id_title_layout);

        mBtnOk = (Button) findComponentById(ResourceTable.Id_btn_ok);
        mBtnOk.setClickedListener(this);

        mBtnPre = (Text) findComponentById(ResourceTable.Id_btn_preview);
        mBtnPre.setClickedListener(this);

        mFooterBar = findComponentById(ResourceTable.Id_footer_bar);
        mllDir = findComponentById(ResourceTable.Id_ll_dir);
        mllDir.setClickedListener(this);
        mtvDir = (Text) findComponentById(ResourceTable.Id_tv_dir);
        Checkbox originalimage = (Checkbox) findComponentById(ResourceTable.Id_cb_calculate_async);
        originalimage.setClickedListener(this);
        DependentLayout recycleLayout = (DependentLayout) findComponentById(ResourceTable.Id_recycle_layout);
        if (imagePicker.getStatus() == 0) {
            if (imagePicker.isMultiMode()) {
                mBtnOk.setVisibility(Component.VISIBLE);
                mtvDir.setVisibility(Component.HIDE);
                originalimage.setVisibility(Component.HIDE);
                mBtnPre.setVisibility(Component.HIDE);
                ShapeElement shapeElement = new ShapeElement();
                shapeElement.setRgbColor(new RgbColor(Color.getIntColor("#FFFFFF")));
                mFooterBar.setBackground(shapeElement);
            } else {
                mBtnOk.setVisibility(Component.VISIBLE);
                mtvDir.setVisibility(Component.HIDE);
                originalimage.setVisibility(Component.HIDE);
                mBtnPre.setVisibility(Component.HIDE);
                ShapeElement shapeElement = new ShapeElement();
                shapeElement.setRgbColor(new RgbColor(Color.getIntColor("#FFFFFF")));
                mFooterBar.setBackground(shapeElement);
            }
            try {
                int color = resManager.getElement(ResourceTable.Color_image_color_black).getColor();
                getWindow().setStatusBarColor(color);
            } catch (IOException | NotExistException | WrongTypeException e) {
                e.fillInStackTrace();
            }
        } else {
            if (imagePicker.getStatus() == 1) {
                ShapeElement shapeElementRecy = new ShapeElement();
                shapeElementRecy.setRgbColor(RgbColor.fromArgbInt(Color.getIntColor("#CCFFFFFF")));
                recycleLayout.setBackground(shapeElementRecy);
                ShapeElement shapeElement = new ShapeElement();
                shapeElement.setRgbColor(RgbColor.fromArgbInt(Color.getIntColor("#3F51B5")));
                titleLayout.setBackground(shapeElement);
                try {
                    int color = resManager.getElement(ResourceTable.Color_colorPrimary).getColor();
                    getWindow().setStatusBarColor(color);
                } catch (IOException | NotExistException | WrongTypeException e) {
                    e.fillInStackTrace();
                }
            }
        }

        mImageFolderAdapter = new ImageFolderAdapter(this, null);
        listProvider = new ImageRecyclerProvider(this, null);

        onImageSelected(0, null, false);

        if (verifySelfPermission(SystemPermission.READ_USER_STORAGE) == IBundleManager.PERMISSION_GRANTED
                && verifySelfPermission(SystemPermission.READ_MEDIA) == IBundleManager.PERMISSION_GRANTED
                && verifySelfPermission(SystemPermission.MEDIA_LOCATION) == IBundleManager.PERMISSION_GRANTED) {
            new ImageDataSource(this, null, this);
        } else {
            requestPermissionsFromUser(new String[]{SystemPermission.READ_USER_STORAGE, SystemPermission.READ_MEDIA, SystemPermission.MEDIA_LOCATION}, REQUEST_PERMISSION_STORAGE);
        }
    }

    private void takePic() {
        imagePicker.takePicture(this);
    }

    @Override
    public void onRequestPermissionsFromUserResult(int requestCode, String[] permissions, int[] grantResults) {
        super.onRequestPermissionsFromUserResult(requestCode, permissions, grantResults);
        if (requestCode == REQUEST_PERMISSION_STORAGE) {
            if (grantResults.length > 0 && grantResults[0] == IBundleManager.PERMISSION_GRANTED) {
                new ImageDataSource(this, null, this);
            } else {
                showToast("权限被禁止，无法选择本地图片");
            }
        } else if (requestCode == REQUEST_PERMISSION_CAMERA) {
            if (grantResults.length > 0 && grantResults[0] == IBundleManager.PERMISSION_GRANTED) {
                takePic();
            } else {
                showToast("权限被禁止，无法打开相机");
            }
        }
    }

    @Override
    protected void onStop() {
        imagePicker.removeOnImageSelectedListener(this);
        super.onStop();
    }

    @Override
    public void onClick(Component v) {
        int id = v.getId();
        if (id == ResourceTable.Id_btn_ok) {
            Intent intent = new Intent();
            intent.setParam(ImagePicker.EXTRA_RESULT_ITEMS, imagePicker.getSelectedImages());
            setResult(ImagePicker.RESULT_CODE_ITEMS, intent); // 多选不允许裁剪裁剪，返回数据
            terminateAbility();
        } else if (id == ResourceTable.Id_ll_dir) {
            if (mImageFolders == null) {
                return;
            }
            // 点击文件夹按钮
            createPopupFolderList();
            mImageFolderAdapter.refreshData(mImageFolders); // 刷新数据
        } else if (id == ResourceTable.Id_btn_back) {
            // 点击返回按钮
            terminateAbility();
        } else if (id == ResourceTable.Id_cb_calculate_async) {
            // 点击原图
            imageFileListContainer.setVisibility(Component.HIDE);
        }
    }

    /**
     * 创建弹出的ListView
     */
    private void createPopupFolderList() {
        imageFileListContainer.setItemProvider(mImageFolderAdapter);
        imageFileListContainer.setItemClickedListener(new ListContainer.ItemClickedListener() {
            @Override
            public void onItemClicked(ListContainer listContainer, Component component, int position, long l) {
                mImageFolderAdapter.setSelectIndex(position);
                imageFileListContainer.setVisibility(Component.HIDE);
                ImageFolder imageFolder = (ImageFolder) listContainer.getItemProvider().getItem(position);

                if (null != imageFolder) {
                    if (imagePicker.getCurrentImageFolderPosition() != position) {
                        listProvider.refreshData(imageFolder.images);
                        mtvDir.setText(imageFolder.name);
                    }
                }
                imagePicker.setCurrentImageFolderPosition(position);
            }
        });
        if (imageFileListContainer.getVisibility() == Component.VISIBLE) {
            imageFileListContainer.setVisibility(Component.HIDE);
        } else {
            imageFileListContainer.setVisibility(Component.VISIBLE);
        }
    }

    /**
     * onImagesLoaded
     *
     * @param imageFolders imagefolders
     */
    @Override
    public void onImagesLoaded(List<ImageFolder> imageFolders) {
        this.mImageFolders = imageFolders;
        imagePicker.setImageFolders(imageFolders);
        if (imageFolders.size() == 0) {
            listProvider.refreshData(null);
        } else {
            listProvider.refreshData(imageFolders.get(0).images);
        }
        listProvider.setOnImageItemClickListener(this);
        listContainer.setItemProvider(listProvider);
        mImageFolderAdapter.refreshData(imageFolders);
    }

    /**
     * onImageItemClick
     *
     * @param view view
     * @param position position
     * @param imageItem imageItem
     */
    @Override
    public void onImageItemClick(Component view, ImageItem imageItem, int position) {
        // 根据是否有相机按钮确定位置
        position = imagePicker.isShowCamera() ? position - 1 : position;
        if (imagePicker.isMultiMode()) {
            imageFileListContainer.setVisibility(Component.HIDE);
        } else {
            imageFileListContainer.setVisibility(Component.HIDE);
            imagePicker.clearSelectedImages();
            imagePicker.addSelectedImageItem(position, imagePicker.getCurrentImageFolderItems().get(position), true);
            Intent intent = new Intent();
            intent.setParam(ImagePicker.EXTRA_RESULT_ITEMS, imagePicker.getSelectedImages());
            setResult(ImagePicker.RESULT_CODE_ITEMS, intent); // 单选不需要裁剪，返回数据
            terminateAbility();
        }
    }

    /**
     * onImageSelected
     *
     * @param position position
     * @param isAdd isAdd
     * @param item item
     */
    @Override
    public void onImageSelected(int position, ImageItem item, boolean isAdd) {
        if (imagePicker.getSelectImageCount() > 0) {
            mBtnOk.setText(ResUtil.getString(this, ResourceTable.String_ip_complete, imagePicker.getSelectImageCount(), imagePicker.getSelectLimit()));
            mBtnOk.setEnabled(true);
            mBtnPre.setEnabled(true);
            mBtnPre.setText(ResUtil.getString(this, ResourceTable.String_ip_preview, imagePicker.getSelectImageCount()));
            mBtnPre.setTextColor(new Color(ResUtil.getColor(this, ResourceTable.Color_preview_color)));
            mBtnOk.setTextColor(new Color(ResUtil.getColor(this, ResourceTable.Color_ip_text_primary_inverted)));
            mBtnPre.setClickedListener(new Component.ClickedListener() {
                @Override
                public void onClick(Component component) {
                    imageFileListContainer.setVisibility(Component.HIDE);
                }
            });
        } else {
            mBtnOk.setText(ResUtil.getString(this, ResourceTable.String_ip_complete));
            mBtnOk.setEnabled(false);
            mBtnPre.setText(ResUtil.getString(this, ResourceTable.String_ip_preview));
            mBtnPre.setTextColor(new Color(ResUtil.getColor(this, ResourceTable.Color_preview_color)));
            mBtnPre.setClickedListener(new Component.ClickedListener() {
                @Override
                public void onClick(Component component) {
                    imageFileListContainer.setVisibility(Component.HIDE);
                }
            });
            mBtnOk.setTextColor(new Color(ResUtil.getColor(this, ResourceTable.Color_ip_text_secondary_inverted)));
        }
        for (int i = imagePicker.isShowCamera() ? 1 : 0; i < listProvider.getCount(); i++) {
            if (listProvider.getItem(i).uriSchema != null && listProvider.getItem(i).uriSchema.equals(item.uriSchema)) {
                listProvider.notifyDataSetItemChanged(i);
                return;
            }
        }
    }

    @Override
    protected void onAbilityResult(int requestCode, int resultCode, Intent data) {
        try {
            super.onAbilityResult(requestCode, resultCode, data);

            if (data != null && data.getParams() != null) {

                if (resultCode == ImagePicker.RESULT_CODE_BACK) {
                } else {
                    // 从拍照界面返回
                    // 点击 X , 没有选择照片
                    if (data.getSerializableParam(ImagePicker.EXTRA_RESULT_ITEMS) == null) {
                        // 什么都不做 直接调起相机
                        terminateAbility();
                    } else {
                        // 说明是从裁剪页面过来的数据，直接返回就可以
                        setResult(ImagePicker.RESULT_CODE_ITEMS, data);
                        terminateAbility();
                    }
                }
            } else {
                // 如果是裁剪，因为裁剪指定了存储的Uri，所以返回的data一定为null
                if (resultCode == ImagePicker.RESULT_OK && requestCode == ImagePicker.REQUEST_CODE_TAKE) {

                    /*
                     * 2017-03-21 对机型做旋转处理
                     */
                    String path = imagePicker.getTakeImageFile().getAbsolutePath();

                    ImageItem imageItem = new ImageItem();
                    imageItem.uriSchema = path;
                    imagePicker.clearSelectedImages();
                    imagePicker.addSelectedImageItem(0, imageItem, true);
                    Intent intent = new Intent();
                    intent.setParam(ImagePicker.EXTRA_RESULT_ITEMS, imagePicker.getSelectedImages());
                    setResult(ImagePicker.RESULT_CODE_ITEMS, intent); // 单选不需要裁剪，返回数据
                    terminateAbility();
                } else if (directPhoto) {
                    terminateAbility();
                }
            }
        } catch (Exception e) {
            terminateAbility();
        }
    }
}